package cn.funeralobjects.dictms.web.controller;

import cn.funeralobjects.common.service.*;
import cn.funeralobjects.common.service.exception.OperationException;
import cn.funeralobjects.common.web.controller.*;
import cn.funeralobjects.common.web.controller.converter.ModelMapper;
import cn.funeralobjects.dictms.entity.EDictValue;
import cn.funeralobjects.dictms.model.DictValue;
import cn.funeralobjects.dictms.service.DictValueService;
import cn.funeralobjects.dictms.web.api.DictValueApi;
import cn.funeralobjects.dictms.web.mapper.DictValueMapper;
import cn.funeralobjects.dictms.web.model.MDictValue;
import cn.funeralobjects.dictms.web.model.VDictValue;
import cn.funeralobjects.util.ReactorUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author FuneralObjects
 * Create date: 2020/6/5 10:29 AM
 */
@RestController
@RequestMapping("/dict-value")
public class DictValueController implements DictValueApi,
        CommonModifyController<VDictValue, MDictValue, DictValue, EDictValue, Integer>,
        RestEntityController<VDictValue, EDictValue, Integer>,
        RestCodeController<VDictValue, EDictValue, Integer>,
        RestEnableController<VDictValue, EDictValue, Integer>,
        RestCommitController<Integer> {

    @Resource
    private DictValueService dictValueService;

    @Resource
    private DictValueMapper dictValueMapper;

    @Override
    public ModelMapper<MDictValue, DictValue, EDictValue, VDictValue> modelMapper() {
        return dictValueMapper;
    }

    @Override
    public CommonModifyService<DictValue, EDictValue, Integer> commonModifyService() {
        return dictValueService;
    }

    @Override
    public CodeService<EDictValue, Integer> codeService() {
        return dictValueService;
    }

    @Override
    public CommitService<Integer> commitService() {
        return dictValueService;
    }

    @Override
    public EnableService<EDictValue, Integer> enableService() {
        return dictValueService;
    }

    @Override
    public EntityService<EDictValue, Integer> entityService() {
        return dictValueService;
    }

    @Override
    public IdService<Integer> idService() {
        return dictValueService;
    }


    @PostMapping("/dict-{dictId}")
    @Override
    public Mono<VDictValue> addByDictId(@PathVariable Integer dictId,
                                        @Validated @RequestBody MDictValue dictValue) {
        return Mono.just(dictValueMapper.toModify(dictValue).setDictId(dictId))
                .map(dictValueService::add)
                .map(this::toVo);
    }

    @PutMapping("/dict-{dictId}/{id}")
    @Override
    public Mono<Void> updateByDictId(@PathVariable Integer dictId,
                                     @PathVariable Integer id,
                                     @Validated @RequestBody MDictValue dictValue) {
        return Mono.just(dictValueMapper.toModify(dictValue).setDictId(dictId))
                .flatMap(ReactorUtils.thenEmpty(modify -> {
                    dictValueService.update(id, modify);
                }));
    }

    @GetMapping("/dict-{dictId}/{id}")
    @Override
    public Mono<VDictValue> findByDictIdAndId(@PathVariable Integer dictId,
                                              @PathVariable Integer id) {
        return Mono.defer(() -> Mono.just(dictValueService.findByIdInDict(id, dictId))
                .flatMap(ReactorUtils::getOrEmpty)
                .map(this::toVo));
    }

    @Override
    public Mono<VDictValue> add(MDictValue dictValue) {
        return Mono.error(new OperationException("NOT SUPPORT METHOD"));
    }

    @Override
    public Mono<Void> update(Integer integer, MDictValue dictValue) {
        return Mono.error(new OperationException("NOT SUPPORT METHOD"));
    }

    @GetMapping("/dict-{dictId}/all")
    @Override
    public Mono<List<VDictValue>> findAllByDictId(@PathVariable Integer dictId,
                                                  @RequestParam(value = "value-like", required = false) String valueLike) {
        return Mono.defer(() -> Mono.just(dictValueService.findAllByDictIdAndValueLike(dictId, valueLike).stream().map(this::toVo).collect(Collectors.toList())));
    }

    @GetMapping("/dict-{dictId}/page/{num}-{size}")
    @Override
    public Mono<Page<VDictValue>> findPageByDictId(@PathVariable Integer dictId,
                                                   @PathVariable Integer num,
                                                   @PathVariable Integer size,
                                                   @RequestParam(value = "value-like", required = false) String valueLike) {
        return Mono.defer(() -> Mono.just(dictValueService.findPageByDictIdAndValueLike(PageRequest.of(num, size), dictId, valueLike).map(this::toVo)));
    }


}
